package com.grad.webstudy.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.grad.webstudy.constants.RedisConstants;
import com.grad.webstudy.constants.RoleConstants;
import com.grad.webstudy.context.UserContext;
import com.grad.webstudy.dao.RoleDao;
import com.grad.webstudy.enums.ExceptionEnums;
import com.grad.webstudy.exceptions.CustomException;
import com.grad.webstudy.model.Role;
import com.grad.webstudy.model.RoleAuth;
import com.grad.webstudy.model.User;
import com.grad.webstudy.service.RoleAuthService;
import com.grad.webstudy.service.RoleService;
import com.grad.webstudy.service.RoleUserService;
import com.grad.webstudy.utils.RedisUtil;
import com.grad.webstudy.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author: zjf
 * @Date: 2020/1/18 15:32
 * @Description:
 */
@Service
@Transactional
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RoleDao roleDao;


    @Autowired
    private RoleAuthService roleAuthService;


    @Autowired
    private RoleUserService roleUserService;

    @Override
    public boolean checkRoleIds(List<Integer> roleIds) {

        return roleDao.checkRoleIds(roleIds).size() == roleIds.size();
    }

    @Override
    public List<String> getRoleNameByIds(List<Integer> roleId) {
        List<String> roleNames = new ArrayList<>();
        if (roleId.size() > 0) {
            List<Role> roles = roleDao.getRoleNameByIds(roleId);
            for (Role role : roles) {
                roleNames.add(role.getRoleName());
            }
        }
        return roleNames;
    }

    @Override
    public boolean addRole(String roleName, String roleDesc, String authIds) {
        User loginUser = UserContext.getLoginUser();
        Role role = new Role();
        role.setCreateTime(new Date());
        role.setRoleName(roleName);
        role.setCreater(loginUser.getUsername());
        role.setRoleDesc(roleDesc);

        boolean addAuth = true;
        boolean addRole = true;
        addRole = roleDao.addRole(role) > 0;

        if (authIds.length() > 0) {
            addAuth = roleAuthService.addRoleAuth(role.getId(), authIds);
        }

        redisUtil.delByPrefix(RedisConstants.REDIS_ROLE_KEY_PREFIX);
        return addRole && addAuth;
    }

    @Override
    public boolean deleteRoles(String ids) {
        List<String> deleteIds = Arrays.asList(ids.split(","));
        if (deleteIds.size() <= 0) {
            throw new CustomException(ExceptionEnums.CUSTOM_ERROR.getCode(),
                    "传入的参数ids[" + ids + "]有误");
        }

        if (deleteIds.contains(String.valueOf(RoleConstants.ADMIN)) ||
                deleteIds.contains(String.valueOf(RoleConstants.EVERYONE)) ||
                deleteIds.contains(String.valueOf(RoleConstants.TEACHER))) {
            throw new CustomException(ExceptionEnums.CUSTOM_ERROR.getCode(),
                    "不能删除系统固定用户");
        }


        redisUtil.delByPrefix(RedisConstants.REDIS_ROLE_KEY_PREFIX);

        return roleDao.deleteRoles(deleteIds) == deleteIds.size() &&
                roleAuthService.deleteRoleAuth(deleteIds) &&
                roleUserService.deleteRoleUsersByRoleIds(deleteIds);
    }

    @Override
    public boolean updateRole(Integer id, String roleName, String roleDesc) {
        redisUtil.delByPrefix(RedisConstants.REDIS_ROLE_KEY_PREFIX);
        return roleDao.update(id, roleName, roleDesc) > 0;
    }

    @Override
    public PageInfo queryRolesByPage(int currPage, int pageSize, String keyword) {
        String key = RedisConstants.REDIS_ROLE_KEY_PREFIX + "queryAll" + currPage + "-" + pageSize+"-"+keyword;
        PageInfo<Role> result;
        if (redisUtil.hasKey(key)) {
            result = (PageInfo<Role>) redisUtil.get(key);
        } else {
            Page page = PageHelper.startPage(currPage, pageSize);
            result = new PageInfo<>(roleDao.selectAll(keyword));

            result.setTotal(page.getTotal());
            result.setPageNum(currPage);
            result.setPageSize(pageSize);
            redisUtil.set(key, result);
        }

        return result;
    }

    @Override
    public List<Role> queryAllRoles() {
        return roleDao.selectAll("");
    }

    @Override
    public boolean changeRoleAuth(int roleId, String authIds) {

        redisUtil.delByPrefix(RedisConstants.REDIS_ROLE_KEY_PREFIX);

        if (roleAuthService.queryRoleAuth(roleId) != null) {
            return roleAuthService.updateRoleAuth(roleId, authIds);
        } else {
            return roleAuthService.addRoleAuth(roleId, authIds);
        }

    }

    @Override
    public RoleVo queryRoleAuth(Integer roleId) {

        RoleAuth roleAuth = roleAuthService.queryRoleAuth(roleId);

        List<String> authIds = Arrays.asList(roleAuth.getAuthIds().split(","));

        return new RoleVo(roleId, authIds);
    }


}
